package material

import (
	"cloud_android_backend/api/common"
	"cloud_android_backend/pkg/middleware/authorization"
	model "cloud_android_backend/pkg/models/users"
	"cloud_android_backend/pkg/modules/material"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/glog"
	rb "modules.tenxcloud.com/common/middleware"
	"modules.tenxcloud.com/common/utility/success"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

func Register(application *gin.RouterGroup) {
	materials := application.Group("material")
	materials.GET("/list", authorization.TokenCheck, List)
	materials.POST("/upload", rb.RequestBody, authorization.TokenCheck, UploadFile)
	materials.POST("/delete", rb.RequestBody, authorization.TokenCheck, DeleteFile)
	materials.POST("/rename", rb.RequestBody, authorization.TokenCheck, RenameFile)
	materials.POST("/download", rb.RequestBody, authorization.TokenCheck, DownloadFiles)
	materials.POST("/transfer", rb.RequestBody, authorization.TokenCheck, TransferFileToPhone)
	materials.GET("/download", authorization.TokenCheck, SecureDownload)
	materials.GET("/downloadtest", SecureDownloadtest)
	video := application.Group("video")
	video.GET("/categories/list", rb.RequestBody, authorization.TokenCheck, CategoryList)
	video.POST("/categories/create", rb.RequestBody, authorization.TokenCheck, CategoryCreate)
	video.POST("/material/list", rb.RequestBody, authorization.TokenCheck, RenameFile)
}
func List(c *gin.Context) {

	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	path := "/fsdata/" + current.UserID
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		// 目录不存在，创建（包括父目录）
		err := os.MkdirAll(path, os.ModePerm)
		if err != nil {
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	} else if err != nil {
		// 其他错误（如权限问题）
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	path = strings.Replace(path, "/fsdata/", "/", -1)
	name := c.Query("name")

	page := 1
	if c.Query("page") != "" {
		page, _ = strconv.Atoi(c.Query("page"))
		if page <= 0 {
			page = 1
		}
	}
	size := 100
	if c.Query("size") != "" {
		size, _ = strconv.Atoi(c.Query("size"))
	}
	cat := c.Query("cat")
	from := (page - 1) * size
	file, err := material.ListFileWithCategory(path, name, c.DefaultQuery("order", "desc"), c.DefaultQuery("sort", "mtime"), cat, from, size)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	c.JSON(success.OK(common.SuccessPagination(file, size, page, int64(file.Total))))
}

func UploadFile(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	file, err := c.FormFile("file")
	if err != nil {
		fmt.Println("获取文件失败: %v", err)
		//c.String(http.StatusBadRequest, "获取文件失败: %v", err)
		c.JSON(common.ErrorResponse("get file failed"))
		return
	}

	// 创建保存目录
	saveDir := "/fsdata/" + current.UserID
	if err := os.MkdirAll(saveDir, os.ModePerm); err != nil {
		//c.String(http.StatusInternalServerError, "创建目录失败: %v", err)
		c.JSON(common.ErrorResponse("create directory failed"))
		return
	}

	// 保存文件
	dst := filepath.Join(saveDir, file.Filename)
	if err := c.SaveUploadedFile(file, dst); err != nil {
		//c.String(http.StatusInternalServerError, "保存文件失败: %v", err)
		c.JSON(common.ErrorResponse("save file failed"))
		return
	}

	c.JSON(success.OK(common.SuccessResponse("上传成功")))
}

type DeleteFileReq struct {
	Name []string `json:"name"`
}

func DeleteFile(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	body, _ := c.Get(rb.RequestBodyKey)
	req := DeleteFileReq{}
	if err := json.Unmarshal(body.([]byte), &req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	current := li.(*model.User)
	path := "/fsdata/" + current.UserID
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		// 目录不存在，创建（包括父目录）
		err := os.MkdirAll(path, os.ModePerm)
		if err != nil {
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	}
	for _, v := range req.Name {
		_, err := os.Stat(path + "/" + v)
		if os.IsNotExist(err) {
			c.AbortWithStatusJSON(common.ErrorResponse("file not exist"))
			return
		}
		err = os.RemoveAll(path + "/" + v)
		if err != nil {
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	}
	//name := c.Query("name")
	//_, err = os.Stat(path + "/" + name)
	//if os.IsNotExist(err) {
	//	c.AbortWithStatusJSON(common.ErrorResponse("file not exist"))
	//	return
	//}
	//err = os.RemoveAll(path + "/" + name)
	//if err != nil {
	//	c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
	//	return
	//}
	c.JSON(success.OK(common.SuccessResponse("删除成功")))
}

type RenameFileReq struct {
	OldName []string `json:"oldName"`
	NewName []string `json:"newName"`
}

func RenameFile(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	body, _ := c.Get(rb.RequestBodyKey)
	req := RenameFileReq{}
	if err := json.Unmarshal(body.([]byte), &req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	current := li.(*model.User)
	path := "/fsdata/" + current.UserID
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		// 目录不存在，创建（包括父目录）
		err := os.MkdirAll(path, os.ModePerm)
		if err != nil {
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	}
	oldname := req.OldName
	newname := req.NewName
	if len(oldname) == 0 || len(newname) == 0 {
		c.AbortWithStatusJSON(common.ErrorResponse("oldName or newName is missing"))
		return
	}
	//if len(oldname) == 1 {
	//	err = os.Rename(oldname[0], newname)
	//	if err != nil {
	//		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
	//		return
	//	}
	//}
	if len(oldname) > 0 {
		for i, v := range oldname {
			err := os.Rename(path+"/"+v, path+"/"+newname[i])
			if err != nil {
				c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
				return
			}
		}
	}

	c.JSON(success.OK(common.SuccessResponse("重命名成功")))
}

type DownloadFileReq struct {
	Names []string `json:"names"`
}

func DownloadFiles(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}

	body, _ := c.Get(rb.RequestBodyKey)
	req := DownloadFileReq{}
	if err := json.Unmarshal(body.([]byte), &req); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}

	current := li.(*model.User)
	name := req.Names
	if len(name) == 0 {
		glog.Errorf("no files specified for download")
		c.AbortWithStatusJSON(common.ErrorResponse("no files specified for download"))
		return
	}

	// 多个文件返回JSON列表
	files := make([]map[string]interface{}, 0)
	for _, filename := range name {
		filePath := current.UserID + "/" + filename
		fileData, err := material.DownloadFile(filePath)
		if err != nil {
			glog.Errorf("failed to download file %s: %v", filePath, err)
			continue
		}

		files = append(files, map[string]interface{}{
			"name":    filename,
			"content": fileData,
		})
	}

	c.JSON(success.OK(common.SuccessResponse(files)))
}

func SecureDownload(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	path := "/fsdata/" + current.UserID

	fname := c.Query("filename")
	fullPath := filepath.Join(path, fname)

	// 设置响应头，告诉浏览器这是一个文件下载
	c.Header("Content-Disposition", "attachment; filename="+filepath.Base(fullPath))
	c.Header("Content-Type", "application/octet-stream")

	// 发送文件
	c.File(fullPath)
}
func SecureDownloadtest(c *gin.Context) {

	path := "/fsdata/" + "UID-NiaZXgcB6c8M"

	fname := c.Query("filename")
	fullPath := filepath.Join(path, fname)

	// 设置响应头，告诉浏览器这是一个文件下载
	c.Header("Content-Disposition", "attachment; filename="+filepath.Base(fullPath))
	c.Header("Content-Type", "application/octet-stream")

	// 发送文件
	c.File(fullPath)

}

func TransferFileToPhone(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	var transferFileReq material.TransferFileReq
	body, _ := c.Get(rb.RequestBodyKey)
	if err := json.Unmarshal(body.([]byte), &transferFileReq); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	err := material.TransferFileToInstances(transferFileReq, current.UserID)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	c.JSON(success.OK(common.SuccessResponse("传输成功")))
}
